package so.ruo.api;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.imageio.ImageIO;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.attilax.io.filex;
import com.attilax.lang.IniEx;
import com.attilax.net.websitex;
import com.attilax.shbye.YejmX;

public class SinaAuth extends BaseAuth {

	private HttpClientContext context = null;
	private CloseableHttpClient httpclient = null;
	private CloseableHttpResponse response = null;
	private HttpHost targetHost = null;
	private HttpHost proxyHost = null;
	private CookieStore cookieStore = null;
	private Proxy proxy = null;
	private Header[] headers = null;
	private RequestConfig config = null;
	private Map<String, String> headMap = null;
	private String charset = "utf-8";
	private long contentLength = -1;
	private String returns = null;
	private LaxRedirectStrategy redirectStrategy = null;
	private String httpType = "POST";

	public SinaAuth() {
		if (redirectStrategy == null) {
			redirectStrategy = new LaxRedirectStrategy();
		}
		if (httpclient == null) {
			PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
			connManager.setMaxTotal(200);
			connManager.setDefaultMaxPerRoute(20);
			connManager.closeIdleConnections(120, TimeUnit.SECONDS);
			httpclient = HttpClients.custom().setRedirectStrategy(redirectStrategy).setConnectionManager(connManager).build();
		}
		if (cookieStore == null) {
			cookieStore = new BasicCookieStore();
		}
		if (context == null) {
			context = HttpClientContext.create();
			context.setCookieStore(cookieStore);
		}
	}
	public static String file_save_Path  ;
	public static  YejmX yjmx=new YejmX();
	@SuppressWarnings("static-access")
	public String login(String host, String site, Map<String, String> postInfo) {
		System.out.println("");
		 try {
			yjmx.inix();
		} catch (IniEx e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			throw new RuntimeException(e1);
		
		}catch(Throwable e)
		 {
			e.printStackTrace();
			throw new RuntimeException(e);
		 }
		 
		HttpPost httpPost = new HttpPost(site);
		String content = null;
		if (proxy != null) {
			System.out.println();
			targetHost = new HttpHost(host, 80, "http"); // 设定目标站点
			System.out.println(proxy.getIp());
			System.out.println(proxy.getPort());
			System.out.println(proxy.getType().name());
			proxyHost = new HttpHost(proxy.getIp(), proxy.getPort(), proxy.getType().name()); // 设置代理对象 ip/代理名称,端口
			config = RequestConfig.custom().setProxy(proxyHost).build();
			httpPost.setConfig(config);
		}

		try {
			// 获得rsaPubkey,rsakv,servertime等参数值
			HashMap<String, String> params = preLogin(encodeAccount(postInfo.get("mobile")));

			// https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)&_=1437724381898

			httpPost.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
			httpPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1");
			httpPost.setHeader("Accept-Encoding", "gzip, deflate");
			httpPost.setHeader("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3");
			httpPost.setHeader("Accept-Charset", "GB2312,utf-8;q=0.7,*;q=0.7");
			httpPost.setHeader("Referer", "http://weibo.com/?c=spr_web_sq_firefox_weibo_t001");
			httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

			String nonce = makeNonce(6);

			List<NameValuePair> nvps = new ArrayList<NameValuePair>();
			nvps.add(new BasicNameValuePair("encoding", "UTF-8"));
			nvps.add(new BasicNameValuePair("entry", "music"));
			nvps.add(new BasicNameValuePair("gateway", "1"));
			nvps.add(new BasicNameValuePair("from", ""));
			nvps.add(new BasicNameValuePair("savestate", "30"));
			nvps.add(new BasicNameValuePair("useticket", "0"));
			nvps.add(new BasicNameValuePair("pagerefer", ""));
			nvps.add(new BasicNameValuePair("vsnf", "1"));
			nvps.add(new BasicNameValuePair("su", encodeAccount(postInfo.get("mobile"))));
			nvps.add(new BasicNameValuePair("service", "music"));
			nvps.add(new BasicNameValuePair("sr", "1920*1080"));
			nvps.add(new BasicNameValuePair("cdult", "3"));
			nvps.add(new BasicNameValuePair("domain", "sina.com.cn"));
			nvps.add(new BasicNameValuePair("prelt", "0"));
			nvps.add(new BasicNameValuePair("returntype", "META"));
			nvps.add(new BasicNameValuePair("nonce", nonce));
			nvps.add(new BasicNameValuePair("pwencode", "rsa2"));
			nvps.add(new BasicNameValuePair("rsakv", params.get("rsakv")));
			nvps.add(new BasicNameValuePair("servertime", params.get("servertime")));
			// nvps.add(new BasicNameValuePair("sp", new SinaSSOEncoder().encode(p, data, nonce)));

			/******************** *加密密码 ***************************/
			ScriptEngineManager sem = new ScriptEngineManager();
			ScriptEngine se = sem.getEngineByName("javascript");
			se.eval(SinaSSOEncoder.getJs());
			String pass = "";

			if (se instanceof Invocable) {
				Invocable invoke = (Invocable) se;
				// 调用preprocess方法，并传入两个参数密码和验证码
				pass = invoke.invokeFunction("getpass", postInfo.get("password"), params.get("servertime"), nonce, params.get("pubkey")).toString();
			}

			// nvps.add(new BasicNameValuePair("sp", postInfo.get("password")));
			nvps.add(new BasicNameValuePair("sp", pass));
			nvps.add(new BasicNameValuePair("url", "http://weibo.com/ajaxlogin.php?framelogin=1&callback=parent.sinaSSOController.feedBackUrlCallBack"));

			//ati ------------------------
			 file_save_Path = "c:/0jpg/"+filex.getUUidName()+".jpg";
		//	websitex.WebpageContent_jpg("http://login.sina.com.cn/cgi/pin.php?r=95220199&s=0&p=xd-976f533eb801fa7b94804eeea4b5f2c236bd", file_save_Path);
			
			
			// nvps.add(new BasicNameValuePair("ssosimplelogin", "1"));

			

			CloseableHttpResponse response = null;
			String charset = "GBK";
			if (proxy != null) {
				//http://i.sso.sina.com.cn:80   
				//POST http://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.15)&_=1440334201783 HTTP/1.1
				   HttpGet get = new HttpGet("http://login.sina.com.cn/cgi/pin.php");  
				   HttpResponse response_img=   httpclient.execute(targetHost,get,context);  
			        File storeFile = new File(file_save_Path);  
			        FileOutputStream output = new FileOutputStream(storeFile);  
			        //得到网络资源的字节数组,并写入文件  
			        InputStream content2 = response_img.getEntity().getContent();
			        byte b[] = new byte[1024*1000];
			        content2.read(b);
					output.write(b);  
			        output.close();  
			        BufferedImage img=ImageIO.read(new File(file_save_Path));
					   String rzt= 	yjmx.getResult(img);
					String captCode=rzt;
					System.out.println("---captcode:"+captCode);
					nvps.add(new BasicNameValuePair("door", captCode));
					httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
				response = httpclient.execute(targetHost, httpPost, context);
			} else {
				httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
				response = httpclient.execute(httpPost, context);
			}

			int statusCode = response.getStatusLine().getStatusCode();
			if (statusCode == HttpStatus.SC_OK) {
				// 获取响应实体
				HttpEntity entity = response.getEntity();
				if (entity != null) {

					content = EntityUtils.toString(entity, charset);

					// 打印响应内容长度
					System.out.println("Response content length: " + entity.getContentLength());
					// 打印响应内容
					System.out.println("Response content: " + content);
					// EntityUtils.consume(entity);
					String location = null;
					String errInfo = null;
					try {
						// System.out.println("content----------" + content);
						String regex = "location\\.replace\\(\'(.+?)\'\\);";
						Pattern p = Pattern.compile(regex);
						Matcher m = p.matcher(content);
						if (m.find()) {
							location = m.group(1);
							if (location.contains("reason=")) {
								errInfo = location.substring(location.indexOf("reason=") + 7);
								errInfo = URLDecoder.decode(errInfo, "GBK");
							} else {
								httpPost.setURI(new URI(location));
								HttpTools tool = new HttpTools();
								tool.setContext(context);
								tool.setHttpclient(httpclient);
								tool.setProxy(proxy);
								tool.setTargetHost(targetHost);
								tool.setProxyHost(proxyHost);
								content = tool.getRequest(location);
							}
						}

					} catch (ClientProtocolException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					}

				}
			} else if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY || statusCode == HttpStatus.SC_MOVED_PERMANENTLY) {

				System.out.println("当前页面发生重定向了---");

				Header[] headers = response.getHeaders("Location");

				if (headers != null && headers.length > 0) {
					String redirectUrl = headers[0].getValue();
					System.out.println("重定向的URL:" + redirectUrl);

					redirectUrl = redirectUrl.replace(" ", "%20");
					Thread.sleep(3000);
					HttpGet httpget = new HttpGet(redirectUrl);
					System.out.println("Executing request " + httpget.getRequestLine());
					response = httpclient.execute(httpget, context);
					System.out.println("----------------------------------------");
					System.out.println(response.getStatusLine());
					System.out.println("-----" + EntityUtils.toString(response.getEntity(), charset));// .contains("user62323671")
					EntityUtils.consume(response.getEntity());
				}
			}
			return content;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(e.getMessage());
			throw new RuntimeException(e);
			// logger.info(e.getMessage());
		}

		//return null;
	}

	/**
	 * 根据URL,get网页
	 * 
	 * @param url
	 * @throws IOException
	 */
	private String get(String url) throws IOException {

		HttpGet httpGet = new HttpGet(url);
		HttpResponse response = null;
		if (targetHost == null) {
			System.out.println("++++++++++++++++++");
		}
		if (proxy != null) {
			response = httpclient.execute(targetHost, httpGet, context);
		} else {
			response = httpclient.execute(httpGet, context);
		}

		System.out.println(response.getStatusLine());
		HttpEntity entity = response.getEntity();
		String result = dump(entity);
		httpGet.abort();
		return result;
	}

	/**
	 * 新浪微博预登录，获取密码加密公钥
	 * 
	 * @param unameBase64
	 * @return 返回从结果获取的参数的哈希表
	 * @throws IOException
	 */
	private HashMap<String, String> preLogin(String unameBase64) throws IOException {
		String url = "http://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=&rsakt=mod&client=ssologin.js(v1.4.5)&_=" + "_=" + new Date().getTime();
		return getParaFromResult(get(url));
	}

	/**
	 * 从新浪返回的结果字符串中获得参数
	 * 
	 * @param result
	 * @return
	 */
	private static HashMap<String, String> getParaFromResult(String result) {
		HashMap<String, String> hm = new HashMap<String, String>();
		result = result.substring(result.indexOf("{") + 1, result.indexOf("}"));
		String[] r = result.split(",");
		String[] temp;
		for (int i = 0; i < r.length; i++) {
			temp = r[i].split(":");
			for (int j = 0; j < 2; j++) {
				if (temp[j].contains("\""))
					temp[j] = temp[j].substring(1, temp[j].length() - 1);
			}
			hm.put(temp[0], temp[1]);
		}
		return hm;
	}

	/**
	 * 打印页面
	 * 
	 * @param entity
	 * @throws IOException
	 */
	private static String dump(HttpEntity entity) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(entity.getContent(), "utf8"));
		return IOUtils.toString(br);
	}

	private static String encodeAccount(String account) {
		String userName = "";
		try {
			userName = Base64.encodeBase64String(URLEncoder.encode(account, "UTF-8").getBytes());
			// userName = BASE64Encoder.encode(URLEncoder.encode(account,"UTF-8").getBytes());
		} catch (UnsupportedEncodingException e) {
			System.out.println(e.getMessage());
			e.printStackTrace();
		}
		return userName;
	}

	private static String makeNonce(int len) {
		String x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
		String str = "";
		for (int i = 0; i < len; i++) {
			str += x.charAt((int) (Math.ceil(Math.random() * 1000000) % x.length()));
		}
		return str;
	}

	public HttpClientContext getContext() {
		return context;
	}

	public void setContext(HttpClientContext context) {
		this.context = context;
	}

	public CloseableHttpClient getHttpclient() {
		return httpclient;
	}

	public void setHttpclient(CloseableHttpClient httpclient) {
		this.httpclient = httpclient;
	}

	public HttpHost getTargetHost() {
		return targetHost;
	}

	public void setTargetHost(HttpHost targetHost) {
		this.targetHost = targetHost;
	}

	public HttpHost getProxyHost() {
		return proxyHost;
	}

	public void setProxyHost(HttpHost proxyHost) {
		this.proxyHost = proxyHost;
	}

	public CookieStore getCookieStore() {
		return cookieStore;
	}

	public void setCookieStore(CookieStore cookieStore) {
		this.cookieStore = cookieStore;
	}

	public Proxy getProxy() {
		return proxy;
	}

	public void setProxy(Proxy proxy) {
		this.proxy = proxy;
	}

	public Header[] getHeaders() {
		return headers;
	}

	public void setHeaders(Header[] headers) {
		this.headers = headers;
	}

}
